<template>
  <div class="p-4" v-loading="loading">
    <el-form inline v-on:submit.prevent="refresh">
      <el-form-item label="搜索">
        <el-input placeholder="关键字" v-model="keywords" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" :icon="searchIcon" v-on:click="refresh" />
      </el-form-item>
    </el-form>
    <el-table :data="friendLinkList" v-on:sort-change="onSortChange">
      <el-table-column type="index" />
      <el-table-column label="图标" prop="favicon" >
        <template #default="scope">
          <el-image :src="scope.row.favicon" />
        </template>
      </el-table-column>
      <el-table-column label="站点" prop="url" sortable >
        <template #default="scope">
          <a target="_blank" :href="scope.row.url">{{scope.row.url}}</a>
        </template>
      </el-table-column>
      <el-table-column label="名称" prop="title" sortable />
      <el-table-column label="状态" prop="status" sortable >
        <template #default="scope">
          <span>{{friendLinkStatus[scope.row.status].title}}</span>
        </template>
      </el-table-column>
      <el-table-column>
        <template #header>
          <el-button type="text" v-on:click="add">
            <el-icon><plus /></el-icon>
          </el-button>
        </template>
        <template #default="{row}">
          <el-dropdown>
            <template #default>
              <el-icon class="color-text-primary" style="cursor: pointer"><more-filled /></el-icon>
            </template>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item v-if="row.status === pendingStatusValue" v-on:click="pass(row)">通过</el-dropdown-item>
                <el-dropdown-item v-if="row.status === pendingStatusValue" v-on:click="reject(row)">拒绝</el-dropdown-item>
                <el-dropdown-item v-if="row.status === forbiddenStatusValue" v-on:click="enable(row)">启用</el-dropdown-item>
                <el-dropdown-item v-if="row.status === normalStatusValue" v-on:click="disable(row)">禁用</el-dropdown-item>
                <el-dropdown-item v-on:click="edit(row)">编辑</el-dropdown-item>
                <el-dropdown-item v-on:click="remote(row)">删除</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination layout="prev, pager, next" :current-page="pageable.page + 1" :page-size="pageable.size" :total="total" :hide-on-single-page="false" v-on:update:current-page="onPageChange" />
    <el-dialog :title="editDialogTitle" v-model="editDialogVisible" show-close v-on:close="editDialogVisible = false">
      <friend-link-form v-model="friendLink" ref="editForm" />
      <div>
        <el-button type="primary" v-on:click="submitEditForm">提交</el-button>
        <el-button v-on:click="editDialogVisible = false">取消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script lang="ts">
import {Options, Vue} from "vue-class-component";
import {Search} from "@element-plus/icons-vue";
import FriendLink, {
  FRIEND_LINK_STATUS,
  FRIEND_LINK_STATUS_FORBIDDEN, FRIEND_LINK_STATUS_NORMAL,
  FRIEND_LINK_STATUS_PENDING
} from "@/domain/FriendLink";
import Pageable from "@/domain/Pageable";
import FriendLinkService from "@/service/FriendLinkService";
import FriendLinkForm from "@/components/friend-link/FriendLinkForm.vue";
import {ElMessageBox} from "element-plus";

@Options({
  name: "FriendLinkManagement",
  components: {FriendLinkForm}
})
export default class FriendLinkManagement extends Vue{
  searchIcon = Search
  friendLinkStatus = FRIEND_LINK_STATUS
  pendingStatusValue = FRIEND_LINK_STATUS_PENDING
  forbiddenStatusValue = FRIEND_LINK_STATUS_FORBIDDEN
  normalStatusValue = FRIEND_LINK_STATUS_NORMAL

  keywords: string
  friendLinkList: FriendLink[]
  pageable: Pageable = {page: 0, size: 20, sort: []}
  total: number
  loading: boolean
  editDialogVisible: boolean
  editDialogTitle: string
  friendLink?: FriendLink

  data(): any{
    return {
      keywords: "",
      friendLinkList: [],
      pageCount: 0,
      total: 0,
      loading: false,
      editDialogVisible: false,
      friendLink: null,
      editDialogTitle: ""
    }
  }

  async mounted(): Promise<void>{
    await this.refresh();
  }

  async refresh(){
    this.loading = true;
    try {
      const page = await FriendLinkService.page(this.keywords, this.pageable);
      this.friendLinkList = page.content;
      this.total = page.totalElements;
    }finally {
      this.loading = false;
    }
  }

  async onPageChange(page): Promise<void>{
    this.pageable.page = page - 1;
    await this.refresh();
  }

  async onSortChange({prop, order}): Promise<void>{
    if(!prop){
      this.pageable.sort = [];
      this.pageable.page = 0;
      await this.refresh();
    }else{
      this.pageable.sort = [{name: prop, direction: order === "ascending" ? "ASC" : "DESC"}];
      this.pageable.page = 0;
      await this.refresh();
    }
  }

  async pass(link: FriendLink): Promise<void>{
    link.status = this.normalStatusValue;
    this.loading = true;
    try{
      await FriendLinkService.update(link);
    }catch (e) {
      link.status = this.pendingStatusValue;
      throw e;
    }finally {
      this.loading = false;
    }
  }

  async reject(link: FriendLink): Promise<void>{
    link.status = this.forbiddenStatusValue;
    this.loading = true;
    try{
      await FriendLinkService.update(link);
    }catch (e) {
      link.status = this.pendingStatusValue;
      throw e;
    }finally{
      this.loading = false;
    }
  }

  async enable(link: FriendLink): Promise<void>{
    link.status = this.normalStatusValue;
    this.loading = true;
    try{
      await FriendLinkService.update(link);
    }catch (e) {
      link.status = this.forbiddenStatusValue;
      throw e;
    }finally{
      this.loading = false;
    }
  }

  async disable(link: FriendLink): Promise<void>{
    link.status = this.forbiddenStatusValue;
    this.loading = true;
    try{
      await FriendLinkService.update(link);
    }catch (e) {
      link.status = this.normalStatusValue;
      throw e;
    }finally{
      this.loading = false;
    }
  }

  async edit(link: FriendLink): Promise<void>{
    this.friendLink = {...link};
    this.editDialogTitle = "编辑友链";
    this.editDialogVisible = true;
  }

  add(): void{
    this.friendLink = null;
    this.editDialogTitle = "添加友链";
    this.editDialogVisible = true;
  }

  async remote(link: FriendLink): Promise<void>{
    await ElMessageBox.confirm("是否确认删除?", "提示");
    this.loading = true;
    try{
      await FriendLinkService.remove(link.id);
      const index = this.friendLinkList.findIndex(f=>f.id === link.id);
      if(index != -1) {
        this.friendLinkList.splice(index, 1)
      }
    }finally{
      this.loading = false;
    }
  }

  async submitEditForm(): Promise<void>{
    const validateResult = await (this.$refs.editForm as FriendLinkForm).validate();
    if(validateResult !== true) return;
    this.loading = true;
    try{
      if(this.friendLink.id){
        this.friendLink = await FriendLinkService.update(this.friendLink);
        const index = this.friendLinkList.findIndex(f=>f.id === this.friendLink.id)
        if(index !== -1) this.friendLinkList[index] = this.friendLink;
      }else{
        this.friendLink = await FriendLinkService.add(this.friendLink);
        this.friendLinkList.unshift(this.friendLink);
      }
      this.friendLink = null;
      this.editDialogVisible = false;
    }finally{
      this.loading = false;
    }
  }
}
</script>

<style scoped>

</style>
